<?php
/**
 * IBM_DB2-specific installer.
 *
 * @file
 * @ingroup Deployment
 */

/**
 * Class for setting up the MediaWiki database using IBM_DB2.
 *
 * @ingroup Deployment
 * @since 1.17
 */
class Ibm_db2Installer extends DatabaseInstaller {


    protected $globalNames = array(
		'wgDBserver',
		'wgDBname',
		'wgDBuser',
		'wgDBpassword',
		'wgDBmwschema',
	);

    public function getName(){
        return 'ibm_db2';
    }

    public function isCompiled() {
        return self::checkExtension( 'ibm_db2' );
    }

    public function getConnectForm() {
        return
                $this->getTextBox( 'wgDBserver', 'config-db-host', array(), $this->parent->getHelpBox( 'config-db-host-help' ) ) .
                $this->getTextBox( 'wgDBport', 'config-db-port' ) .
                Html::openElement( 'fieldset' ) .
		Html::element( 'legend', array(), wfMsg( 'config-db-wiki-settings' ) ) .
                $this->getTextBox( 'wgDBname', 'config-db-name', array(), $this->parent->getHelpBox( 'config-db-name-help' ) ) .
		$this->getTextBox( 'wgDBmwschema', 'config-db-schema', array(), $this->parent->getHelpBox( 'config-db-schema-help' ) ) .
                Html::closeElement( 'fieldset' ) .
		$this->getInstallUserBox();
    }

    public function submitConnectForm() {
        // Get variables from the request
	$newValues = $this->setVarsFromRequest( array( 'wgDBserver', 'wgDBport',
		'wgDBname', 'wgDBmwschema' ) );

        // Validate them
	$status = Status::newGood();
	if ( !strlen( $newValues['wgDBname'] ) ) {
		$status->fatal( 'config-missing-db-name' );
	} elseif ( !preg_match( '/^[a-zA-Z0-9_]+$/', $newValues['wgDBname'] ) ) {
		$status->fatal( 'config-invalid-db-name', $newValues['wgDBname'] );
	}
	if ( !strlen( $newValues['wgDBmwschema'] ) ) {
		$status->fatal( 'config-invalid-schema' );
	}
	if ( !preg_match( '/^[a-zA-Z0-9_]*$/', $newValues['wgDBmwschema'] ) ) {
		$status->fatal( 'config-invalid-schema', $newValues['wgDBmwschema'] );
	}

        // Submit user box
	if ( $status->isOK() ) {
		$status->merge( $this->submitInstallUserBox() );
	}
	if ( !$status->isOK() ) {
		return $status;
	}

        // Try to connect
	$status->merge( $this->getConnection() );
	if ( !$status->isOK() ) {
		return $status;
	}

        return $status;
        
    }

    public function openConnection() {
        $status = Status::newGood();
	try {
            $db = new DatabaseIbm_db2(
                $this->getVar( 'wgDBserver' ),
                $this->getVar( '_InstallUser' ),
                $this->getVar( '_InstallPassword' ),
                $this->getVar( 'wgDBname' ),
		0,
                $this->getVar( 'wgDBmwschema' )
            );
            $status->value = $db;            
	} catch ( DBConnectionError $e ) {
            $status->fatal( 'config-connection-error', $e->getMessage() );
	}
        return $status;
    }

	public function setupDatabase() {
		$status = $this->getConnection();
		if ( !$status->isOK() ) {
			return $status;
		}
		$conn = $status->value;
		$dbName = $this->getVar( 'wgDBname' );
		if( !$conn->selectDB( $dbName ) ) {
			$conn->query( "CREATE DATABASE " . $conn->addIdentifierQuotes( $dbName ), __METHOD__ );
			$conn->selectDB( $dbName );
		}
		$this->setupSchemaVars();
		return $status;
	}

	/**
	 * Create tables from scratch.
	 * First check if pagesize >= 32k.
	 *
	 * @return Status
	 */
	public function createTables() {
		$status = $this->getConnection();
		if ( !$status->isOK() ) {
			return $status;
		}
		$this->db->selectDB( $this->getVar( 'wgDBname' ) );

		if( $this->db->tableExists( 'user' ) ) {
			$status->warning( 'config-install-tables-exist' );
			return $status;
		}

		/* Check for pagesize */
		$status = $this->checkPageSize();
		if ( !$status->isOK() ) {
			return $status;
		}

		$this->db->setFlag( DBO_DDLMODE ); // For Oracle's handling of schema files
		$this->db->begin( __METHOD__ );

		$error = $this->db->sourceFile( $this->db->getSchema() );
		if( $error !== true ) {
			$this->db->reportQueryError( $error, 0, '', __METHOD__ );
			$this->db->rollback( __METHOD__ );
			$status->fatal( 'config-install-tables-failed', $error );
		} else {
			$this->db->commit( __METHOD__ );
		}
		// Resume normal operations
		if( $status->isOk() ) {
			$this->enableLB();
		}
		return $status;
	}

	/**
	 * Check if database has a tablspace with pagesize >= 32k.
	 *
	 * @return Status
	 */
	public function checkPageSize() {
		$status = $this->getConnection();
		if ( !$status->isOK() ) {
			return $status;
		}
		$this->db->selectDB( $this->getVar( 'wgDBname' ) );

		try {
			$result = $this->db->query( 'SELECT PAGESIZE FROM SYSCAT.TABLESPACES' );
			if( $result == false ) {
				$status->fatal( 'config-connection-error', '' );
			}
			else {
				$nRows = $this->db->numRows( $result );
				while ( $row = $row = $this->db->fetchRow( $result ) ) {
					if( $row[0] >= 32768 ) {
						return $status;
					}
				}
				$status->fatal( 'config-ibm_db2-low-db-pagesize', '' );
			}
		} catch ( DBUnexpectedError $e ) {
			$status->fatal( 'config-connection-error', $e->getMessage() );
		}

		return $status;
	}

    // Não sei se épreciso mudar alguma coisa... Por isso deixei o do MySQL English please
    protected function getTableOptions() {
		$options = array();
		if ( $this->getVar( '_MysqlEngine' ) !== null ) {
			$options[] = "ENGINE=" . $this->getVar( '_MysqlEngine' );
		}
		if ( $this->getVar( '_MysqlCharset' ) !== null ) {
			$options[] = 'DEFAULT CHARSET=' . $this->getVar( '_MysqlCharset' );
		}
		return implode( ', ', $options );
	}


    public function getLocalSettings() {
        $prefix = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBprefix' ) );
        $tblOpts = LocalSettingsGenerator::escapePhpString( $this->getTableOptions() );
        return
"# IBM_DB2 specific settings
\$wgDBprefix         = \"{$prefix}\";
# IBM_DB2 table options to use during installation or update
\$wgDBTableOptions   = \"{$tblOpts}\";";
    }

    public function __construct($parent) {
        parent::__construct($parent);
    }

}
?>
